﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;

namespace OpenLS.Spreadsheet.Formats.Biff.OfficeArt
{
    internal class OfficeArtDgContainer : OfficeArtRecord
    {
        private readonly List<OfficeArtSpgrContainerFileBlock> deletedShapes = new List<OfficeArtSpgrContainerFileBlock>();
        private OfficeArtFDG _drawingData;
        OfficeArtFDG DrawingData
        {
            get
            {
                if (_drawingData == null)
                {
                    _drawingData = new OfficeArtFDG((uint) this.groupShape.Shapes.Count, groupShape.Shapes[groupShape.Shapes.Count - 1].SpId);
                }
                return _drawingData;
            }
        }
            private OfficeArtSpgrContainer groupShape;
        public IEnumerable<OfficeArtSpgrContainerFileBlock> GroupShapes
        {
            get
            {
                if (groupShape == null)
                    yield break;
                foreach (var item in groupShape.Shapes)
                    yield return item;
            }
        }

        private OfficeArtFRITContainer regroupItems;
        private OfficeArtSpContainer shape;
        private OfficeArtSolverContainer solvers2;

        public override RecType RecordType
        {
            get { return RecType.OfficeArtDgContainer; }
        }


        protected override void ReadNoHeader(OfficeArtReadContext context)
        {
            _drawingData = new OfficeArtFDG();
            _drawingData.Read(context);
            regroupItems = context.ReadOptionalRecord<OfficeArtFRITContainer>(RecType.OfficeArtFRITContainer);
            this.groupShape = context.ReadOptionalRecord<OfficeArtSpgrContainer>(RecType.OfficeArtSpgrContainer);
            //            groupShape = new OfficeArtSpgrContainer();
            //          groupShape.Read(reader);
            shape = context.ReadOptionalRecord<OfficeArtSpContainer>(RecType.OfficeArtSpContainer);
            deletedShapes.Clear();

            var item = OfficeArtSpgrContainerFileBlock.ReadOptional(context);
            while (item != null)
            {
                deletedShapes.Add(item);
                item = OfficeArtSpgrContainerFileBlock.ReadOptional(context);
            }
            solvers2 = context.ReadOptionalRecord<OfficeArtSolverContainer>(RecType.OfficeArtSolverContainer);

            // Check drawing data?
        }

        protected override byte Version
        {
            get { return 0xF; }
        }

        protected override int ByteLength
        {
            get
            {
                int result = 0;
                result += DrawingData.FullByteLength;
                if (regroupItems != null)
                    result += regroupItems.FullByteLength;
                if (groupShape != null) result += groupShape.FullByteLength;
                if (shape != null)
                    result += shape.FullByteLength;
                result += Enumerable.Sum(deletedShapes, item => item.FullByteLength);
                if (solvers2 != null)
                    result += solvers2.FullByteLength;
                return result;
            }
        }


        protected override void WriteNoHeader(OfficeArtWriteContext context)
        {
            Contract.Ensures(ByteLength ==
                 context.BaseStream.Position - Contract.OldValue(context.BaseStream.Position));
#if DEBUG
            var pos = context.Writer.BaseStream.Position;
#endif
            context.WriteOptionalChildren(DrawingData, regroupItems, groupShape, shape);
            foreach (OfficeArtSpgrContainerFileBlock item in deletedShapes)
                item.Write(context);
            context.WriteOptionalChild(solvers2);
#if DEBUG
            Contract.Assert(context.Writer.BaseStream.Position - pos == this.ByteLength);
#endif

        }

        public void AddGroupShape(OfficeArtSpContainer officeArtSpContainer)
        {
            if (groupShape == null)
                groupShape = new OfficeArtSpgrContainer();
                this.groupShape.AddShape(officeArtSpContainer);
        }
    }
}